(function($){    
    ujs.define('evt', 'ujs.browser', {
        /**
         * 为元素绑定事件.
         * @param {Object} elem     :   元素DOM对象.
         * @param {String} type     :   事件类型,不加'on'.
         * @param {Function} func   :   事件逻辑.
         */
        addEvent : function(elem, type, func) {
            if(document.addEventListener) {
                elem.addEventListener(type, func, false);
            } else {
                elem.attachEvent('on' + type, func);
            }
        },
        /**
         * 判断是否是有效的键盘输入.
         */
        checkKey : function(keyCode){
            if(keyCode == 32 || keyCode == 229){console.log('空格和异常');return true;}/*空格和异常*/
            if(keyCode>47 && keyCode < 58){console.log('数字');return true;}/*数字*/
            if(keyCode>64 && keyCode < 91){console.log('字母');return true;}/*字母*/
            if(keyCode>95 && keyCode < 108){console.log('数字键盘1');return true;}/*数字键盘1*/
            if(keyCode>108 && keyCode < 112){console.log('数字键盘2');return true;}/*数字键盘2*/
            if(keyCode>185 && keyCode < 193){console.log('符号1');return true;}/*符号1*/
            if(keyCode>218 && keyCode < 223){console.log('符号2');return true;}/*符号2*/
            return false;
        },
        /**
         * 注册调整窗口结束后事件.
         * @param {Function} onResizend :   无参回调函数.
         */
        onResizend : function(onResizend) {
            /**
             * <<<算法说明>>>
             * ---------------------------------------------------------------------------------
             * 1. 默认窗口状态 normal.
             * 2. 调整窗口大小时状态 resizing.
             * 3. 调整窗口大小时设置动作状态为 resizing, 并设置延时任务. 若已存在延时任务,则重新设置.
             * 4. 若500毫秒后没有断续调整大小,则认为调整结束,执行resizend事件.
             */
            var actionState = 'normal', 
                taskPtr = null, 
                timeOutTask = function() {
                    taskPtr && clearTimeout(taskPtr);
                    taskPtr = (function() {
                        onResizend && onResizend();
                        actionState = 'normal';
                    }).defer(500);
                };
        
            this.addEvent(window, 'resize', function() {
                actionState = 'resizing';
                timeOutTask();
            });
        },
        /**
         * 注册开始调整窗口时事件.
         * @param {Function} onResizestart  :   无参回调函数.
         */
        onResizestart : function(onResizestart) {
            var isExecuted = false;
            this.onResizend(function() {
                isExecuted = false;
            });
            this.addEvent(window, 'resize', function() {
                if(!isExecuted) {
                    onResizestart && onResizestart();
                    isExecuted = true;
                }
            });
        },
        /**
         * 注册容器元素的滚动完成事件.
         * 当滚动条距离底部一定距离时触发.
         * scrollEndHandler* {Function} : scroll-end逻辑函数.
         * [context] {DOM} : 默认window, 也可以是div等容器.
         * [bottomMargin] {Number} : 距离滚动条底部的距离, 默认15px.
         */
        onScrollEnd : function(scrollEndHandler, context, bottomMargin){
            if( typeof scrollEndHandler === 'function' ){
                var $context = $( context || window ),
                    isTriggeringHandler = false;
                $context.scroll( function(e){
                    if( Math.abs( $context.scrollTop() + $context.outerHeight() - $context[0].scrollHeight ) < ( bottomMargin || 15 ) ){
                        if(!isTriggeringHandler){
                            isTriggeringHandler = true;
                            scrollEndHandler(e);
                            //等待1.5s,避免scrollEndHandler被重复触发.
                            (function(){
                                isTriggeringHandler = false;
                            }).defer(1500);
                        }
                    }
                });
            }
        }
    });
})($);